<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>进程和线程基础 | whoway</title>
    <meta name="description" content="Personal Blog Website">
    <link rel="icon" href="/images/photo.jpg">
  <link rel="manifest" href="/images/photo.jpg">
  <link rel="apple-touch-icon" href="/images/photo.jpg">
  <meta http-quiv="pragma" cotent="no-cache">
  <meta http-quiv="pragma" cotent="no-cache,must-revalidate">
  <meta http-quiv="expires" cotent="0">
    
    <link rel="preload" href="/assets/css/0.styles.0dbae9ec.css" as="style"><link rel="preload" href="/assets/js/app.c70e21ad.js" as="script"><link rel="preload" href="/assets/js/5.6f47322c.js" as="script"><link rel="prefetch" href="/assets/js/10.15222a53.js"><link rel="prefetch" href="/assets/js/100.7e0e5a86.js"><link rel="prefetch" href="/assets/js/101.efd59f25.js"><link rel="prefetch" href="/assets/js/102.dfbdc06c.js"><link rel="prefetch" href="/assets/js/103.d3ab2109.js"><link rel="prefetch" href="/assets/js/104.117957ef.js"><link rel="prefetch" href="/assets/js/105.046e8ff3.js"><link rel="prefetch" href="/assets/js/106.aebdc17d.js"><link rel="prefetch" href="/assets/js/107.248733c2.js"><link rel="prefetch" href="/assets/js/108.a2fecadc.js"><link rel="prefetch" href="/assets/js/109.35196857.js"><link rel="prefetch" href="/assets/js/11.770642f2.js"><link rel="prefetch" href="/assets/js/110.cf3d973c.js"><link rel="prefetch" href="/assets/js/111.f985889a.js"><link rel="prefetch" href="/assets/js/112.ad614f41.js"><link rel="prefetch" href="/assets/js/113.f666653c.js"><link rel="prefetch" href="/assets/js/114.c6c3f384.js"><link rel="prefetch" href="/assets/js/115.e51d3c2f.js"><link rel="prefetch" href="/assets/js/116.4f4b39f5.js"><link rel="prefetch" href="/assets/js/117.99352e11.js"><link rel="prefetch" href="/assets/js/118.c6ae6572.js"><link rel="prefetch" href="/assets/js/119.4ccbe778.js"><link rel="prefetch" href="/assets/js/12.042a92ff.js"><link rel="prefetch" href="/assets/js/120.edda1c4f.js"><link rel="prefetch" href="/assets/js/121.30a638ed.js"><link rel="prefetch" href="/assets/js/122.6efcefb1.js"><link rel="prefetch" href="/assets/js/123.91e6665b.js"><link rel="prefetch" href="/assets/js/124.f27e3d7e.js"><link rel="prefetch" href="/assets/js/125.c75712d5.js"><link rel="prefetch" href="/assets/js/126.ed756cce.js"><link rel="prefetch" href="/assets/js/127.2f06c74c.js"><link rel="prefetch" href="/assets/js/128.d5f6f30e.js"><link rel="prefetch" href="/assets/js/129.508b7eed.js"><link rel="prefetch" href="/assets/js/13.b5280c37.js"><link rel="prefetch" href="/assets/js/130.dc05f9aa.js"><link rel="prefetch" href="/assets/js/131.e0ba69b1.js"><link rel="prefetch" href="/assets/js/132.d79bcaa4.js"><link rel="prefetch" href="/assets/js/133.34acc01a.js"><link rel="prefetch" href="/assets/js/134.dabf64d5.js"><link rel="prefetch" href="/assets/js/135.ad90c915.js"><link rel="prefetch" href="/assets/js/136.dbb0074f.js"><link rel="prefetch" href="/assets/js/137.284ad365.js"><link rel="prefetch" href="/assets/js/138.a4b6856f.js"><link rel="prefetch" href="/assets/js/139.c9c1e20f.js"><link rel="prefetch" href="/assets/js/14.df02ba38.js"><link rel="prefetch" href="/assets/js/140.8b0a9269.js"><link rel="prefetch" href="/assets/js/141.9c7759c5.js"><link rel="prefetch" href="/assets/js/142.a4201a82.js"><link rel="prefetch" href="/assets/js/143.d7da6e8c.js"><link rel="prefetch" href="/assets/js/144.5e48e65d.js"><link rel="prefetch" href="/assets/js/145.a0e2633c.js"><link rel="prefetch" href="/assets/js/146.3c775f9b.js"><link rel="prefetch" href="/assets/js/147.22add89a.js"><link rel="prefetch" href="/assets/js/148.cfde1009.js"><link rel="prefetch" href="/assets/js/149.ffc835b5.js"><link rel="prefetch" href="/assets/js/15.fbdfc4ee.js"><link rel="prefetch" href="/assets/js/150.406c4b20.js"><link rel="prefetch" href="/assets/js/151.b2040eea.js"><link rel="prefetch" href="/assets/js/152.7bc65661.js"><link rel="prefetch" href="/assets/js/153.1d7c65e3.js"><link rel="prefetch" href="/assets/js/154.1309de49.js"><link rel="prefetch" href="/assets/js/155.81d3ee1f.js"><link rel="prefetch" href="/assets/js/156.154a4ef2.js"><link rel="prefetch" href="/assets/js/16.e5eb6147.js"><link rel="prefetch" href="/assets/js/17.57853c4a.js"><link rel="prefetch" href="/assets/js/18.cb9d7518.js"><link rel="prefetch" href="/assets/js/19.f354dc47.js"><link rel="prefetch" href="/assets/js/2.570d8a23.js"><link rel="prefetch" href="/assets/js/20.b5af7fad.js"><link rel="prefetch" href="/assets/js/21.0b1928fe.js"><link rel="prefetch" href="/assets/js/22.f78666de.js"><link rel="prefetch" href="/assets/js/23.29c3f366.js"><link rel="prefetch" href="/assets/js/24.6f596516.js"><link rel="prefetch" href="/assets/js/25.14067b60.js"><link rel="prefetch" href="/assets/js/26.74ba4989.js"><link rel="prefetch" href="/assets/js/27.13d60edd.js"><link rel="prefetch" href="/assets/js/28.9523cb32.js"><link rel="prefetch" href="/assets/js/29.8ec842e9.js"><link rel="prefetch" href="/assets/js/3.3fb3d2e0.js"><link rel="prefetch" href="/assets/js/30.805597a8.js"><link rel="prefetch" href="/assets/js/31.831b195d.js"><link rel="prefetch" href="/assets/js/32.063c672d.js"><link rel="prefetch" href="/assets/js/33.6d93fac3.js"><link rel="prefetch" href="/assets/js/34.56e8263c.js"><link rel="prefetch" href="/assets/js/35.dbe688bb.js"><link rel="prefetch" href="/assets/js/36.dc5af2c1.js"><link rel="prefetch" href="/assets/js/37.0a7494f6.js"><link rel="prefetch" href="/assets/js/38.fe4fc171.js"><link rel="prefetch" href="/assets/js/39.f5ed5e92.js"><link rel="prefetch" href="/assets/js/4.2c405ec8.js"><link rel="prefetch" href="/assets/js/40.fe7e2714.js"><link rel="prefetch" href="/assets/js/41.30b0811d.js"><link rel="prefetch" href="/assets/js/42.76f52d62.js"><link rel="prefetch" href="/assets/js/43.e7bb0817.js"><link rel="prefetch" href="/assets/js/44.ead0e883.js"><link rel="prefetch" href="/assets/js/45.235df046.js"><link rel="prefetch" href="/assets/js/46.5f09e829.js"><link rel="prefetch" href="/assets/js/47.67116354.js"><link rel="prefetch" href="/assets/js/48.31f34543.js"><link rel="prefetch" href="/assets/js/49.10b5ebba.js"><link rel="prefetch" href="/assets/js/50.c0f0b7f1.js"><link rel="prefetch" href="/assets/js/51.5143f3bf.js"><link rel="prefetch" href="/assets/js/52.eeddfd48.js"><link rel="prefetch" href="/assets/js/53.eb790db5.js"><link rel="prefetch" href="/assets/js/54.8fe5421c.js"><link rel="prefetch" href="/assets/js/55.d8f9004b.js"><link rel="prefetch" href="/assets/js/56.62ac9b92.js"><link rel="prefetch" href="/assets/js/57.a9caec0d.js"><link rel="prefetch" href="/assets/js/58.f93fc522.js"><link rel="prefetch" href="/assets/js/59.a81a03aa.js"><link rel="prefetch" href="/assets/js/6.8c2ea393.js"><link rel="prefetch" href="/assets/js/60.ab782775.js"><link rel="prefetch" href="/assets/js/61.6dd12daf.js"><link rel="prefetch" href="/assets/js/62.76f4b01f.js"><link rel="prefetch" href="/assets/js/63.6f8a4742.js"><link rel="prefetch" href="/assets/js/64.6f8bb1fa.js"><link rel="prefetch" href="/assets/js/65.4120a44b.js"><link rel="prefetch" href="/assets/js/66.360c2d2b.js"><link rel="prefetch" href="/assets/js/67.26f84d32.js"><link rel="prefetch" href="/assets/js/68.68f45e5e.js"><link rel="prefetch" href="/assets/js/69.e311eb56.js"><link rel="prefetch" href="/assets/js/7.6762b2d7.js"><link rel="prefetch" href="/assets/js/70.cea82674.js"><link rel="prefetch" href="/assets/js/71.783ddcf7.js"><link rel="prefetch" href="/assets/js/72.e5467385.js"><link rel="prefetch" href="/assets/js/73.b8fb681b.js"><link rel="prefetch" href="/assets/js/74.1bae37db.js"><link rel="prefetch" href="/assets/js/75.024387e5.js"><link rel="prefetch" href="/assets/js/76.a8e53010.js"><link rel="prefetch" href="/assets/js/77.8c55500a.js"><link rel="prefetch" href="/assets/js/78.7ce90bf5.js"><link rel="prefetch" href="/assets/js/79.ef71713f.js"><link rel="prefetch" href="/assets/js/8.788a6364.js"><link rel="prefetch" href="/assets/js/80.acad589d.js"><link rel="prefetch" href="/assets/js/81.02670d10.js"><link rel="prefetch" href="/assets/js/82.53b7b1ac.js"><link rel="prefetch" href="/assets/js/83.99eb8581.js"><link rel="prefetch" href="/assets/js/84.d1535ce3.js"><link rel="prefetch" href="/assets/js/85.fe2b7de9.js"><link rel="prefetch" href="/assets/js/86.41850272.js"><link rel="prefetch" href="/assets/js/87.1cdc6df9.js"><link rel="prefetch" href="/assets/js/88.01bf3461.js"><link rel="prefetch" href="/assets/js/89.17c69819.js"><link rel="prefetch" href="/assets/js/9.3813842d.js"><link rel="prefetch" href="/assets/js/90.f6ae7e35.js"><link rel="prefetch" href="/assets/js/91.507bc284.js"><link rel="prefetch" href="/assets/js/92.90551782.js"><link rel="prefetch" href="/assets/js/93.dc442d78.js"><link rel="prefetch" href="/assets/js/94.315f4e94.js"><link rel="prefetch" href="/assets/js/95.ccd6c6bf.js"><link rel="prefetch" href="/assets/js/96.0c6d89d0.js"><link rel="prefetch" href="/assets/js/97.1a9f10a9.js"><link rel="prefetch" href="/assets/js/98.43be3caa.js"><link rel="prefetch" href="/assets/js/99.54c8207b.js">
    <link rel="stylesheet" href="/assets/css/0.styles.0dbae9ec.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/" class="home-link router-link-active"><!----> <span class="site-name">whoway</span></a> <div class="links" style="max-width:nullpx;"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">🎓Coding</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/00.Coding/TheBeautyOfProgramming/" class="nav-link">🔖编程之美题解</a></li><li class="dropdown-item"><!----> <a href="/00.Coding/CodeWarehouse/" class="nav-link">🔖代码意识流</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">🚀语言</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/01.Language/Overview/" class="nav-link">🔖概述</a></li><li class="dropdown-item"><!----> <a href="/01.Language/C/" class="nav-link">⭐️C</a></li><li class="dropdown-item"><!----> <a href="/01.Language/Cpp/" class="nav-link">🚀C++</a></li><li class="dropdown-item"><!----> <a href="/01.Language/Java/" class="nav-link">☕️Java</a></li><li class="dropdown-item"><!----> <a href="/01.Language/Python/" class="nav-link">🧩Python3</a></li></ul></div></div><div class="nav-item"><a href="/02.Hardware/" class="nav-link">✔️硬件基础</a></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">⭐️软件基础</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/03.Software/01.DataStructureAndAlgorithm/" class="nav-link">🐾数据结构和算法</a></li><li class="dropdown-item"><!----> <a href="/03.Software/02.OS/" class="nav-link router-link-active">💻操作系统</a></li><li class="dropdown-item"><!----> <a href="/03.Software/03.Net/" class="nav-link">☁️计算机网络</a></li><li class="dropdown-item"><!----> <a href="/03.Software/04.SE/" class="nav-link">✅软件工程</a></li></ul></div></div><div class="nav-item"><a href="/04.Database/" class="nav-link">🎨数据库</a></div><div class="nav-item"><a href="/05.Engineer/" class="nav-link">🔖学术/工程</a></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">⚙️工具</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/06.Tools/01.employment/" class="nav-link">🔖求职</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/02.efficiency/" class="nav-link">🚀效能</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/03.windows/" class="nav-link">⚙️Windows</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/04.design/" class="nav-link">🧩设计</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/05.linux/" class="nav-link">🐉Linux</a></li></ul></div></div><div class="nav-item"><a href="https://github.com/whoway" target="_blank" rel="noopener noreferrer" class="nav-link external">
  GitHub
  <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div> <!----></nav></div></header> <div class="sidebar-mask"></div> <div class="sidebar"><nav class="nav-links"><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">🎓Coding</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/00.Coding/TheBeautyOfProgramming/" class="nav-link">🔖编程之美题解</a></li><li class="dropdown-item"><!----> <a href="/00.Coding/CodeWarehouse/" class="nav-link">🔖代码意识流</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">🚀语言</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/01.Language/Overview/" class="nav-link">🔖概述</a></li><li class="dropdown-item"><!----> <a href="/01.Language/C/" class="nav-link">⭐️C</a></li><li class="dropdown-item"><!----> <a href="/01.Language/Cpp/" class="nav-link">🚀C++</a></li><li class="dropdown-item"><!----> <a href="/01.Language/Java/" class="nav-link">☕️Java</a></li><li class="dropdown-item"><!----> <a href="/01.Language/Python/" class="nav-link">🧩Python3</a></li></ul></div></div><div class="nav-item"><a href="/02.Hardware/" class="nav-link">✔️硬件基础</a></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">⭐️软件基础</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/03.Software/01.DataStructureAndAlgorithm/" class="nav-link">🐾数据结构和算法</a></li><li class="dropdown-item"><!----> <a href="/03.Software/02.OS/" class="nav-link router-link-active">💻操作系统</a></li><li class="dropdown-item"><!----> <a href="/03.Software/03.Net/" class="nav-link">☁️计算机网络</a></li><li class="dropdown-item"><!----> <a href="/03.Software/04.SE/" class="nav-link">✅软件工程</a></li></ul></div></div><div class="nav-item"><a href="/04.Database/" class="nav-link">🎨数据库</a></div><div class="nav-item"><a href="/05.Engineer/" class="nav-link">🔖学术/工程</a></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">⚙️工具</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/06.Tools/01.employment/" class="nav-link">🔖求职</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/02.efficiency/" class="nav-link">🚀效能</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/03.windows/" class="nav-link">⚙️Windows</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/04.design/" class="nav-link">🧩设计</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/05.linux/" class="nav-link">🐉Linux</a></li></ul></div></div><div class="nav-item"><a href="https://github.com/whoway" target="_blank" rel="noopener noreferrer" class="nav-link external">
  GitHub
  <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div> <!----></nav>  <ul class="sidebar-links"><li><div class="sidebar-group first"><p class="sidebar-heading open"><span>进程和线程基础</span> <!----></p> <ul class="sidebar-group-items"><li><a href="/03.Software/02.OS/02.%E7%BA%BF%E7%A8%8B%E5%92%8C%E8%BF%9B%E7%A8%8B%E5%9F%BA%E7%A1%80.html#_1-线程和进程认知" class="sidebar-link">1.线程和进程认知</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/03.Software/02.OS/02.%E7%BA%BF%E7%A8%8B%E5%92%8C%E8%BF%9B%E7%A8%8B%E5%9F%BA%E7%A1%80.html#_1-1-概念：多任务" class="sidebar-link">1.1.概念：多任务</a></li><li class="sidebar-sub-header"><a href="/03.Software/02.OS/02.%E7%BA%BF%E7%A8%8B%E5%92%8C%E8%BF%9B%E7%A8%8B%E5%9F%BA%E7%A1%80.html#_1-2-q：多进程和多线程的对比，主要优势对比" class="sidebar-link">1.2.Q：多进程和多线程的对比，主要优势对比</a></li><li class="sidebar-sub-header"><a href="/03.Software/02.OS/02.%E7%BA%BF%E7%A8%8B%E5%92%8C%E8%BF%9B%E7%A8%8B%E5%9F%BA%E7%A1%80.html#_1-3-q：为什么需要多线程？" class="sidebar-link">1.3.Q：为什么需要多线程？</a></li><li class="sidebar-sub-header"><a href="/03.Software/02.OS/02.%E7%BA%BF%E7%A8%8B%E5%92%8C%E8%BF%9B%E7%A8%8B%E5%9F%BA%E7%A1%80.html#_1-4-q：为什么任何一个线程挂掉都可能直接造成整个进程崩溃？" class="sidebar-link">1.4.Q：为什么任何一个线程挂掉都可能直接造成整个进程崩溃？</a></li></ul></li><li><a href="/03.Software/02.OS/02.%E7%BA%BF%E7%A8%8B%E5%92%8C%E8%BF%9B%E7%A8%8B%E5%9F%BA%E7%A1%80.html#_0-图表记忆" class="sidebar-link">0.图表记忆</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/03.Software/02.OS/02.%E7%BA%BF%E7%A8%8B%E5%92%8C%E8%BF%9B%E7%A8%8B%E5%9F%BA%E7%A1%80.html#图1-进程控制块（pcb）" class="sidebar-link">图1.进程控制块（PCB）</a></li><li class="sidebar-sub-header"><a href="/03.Software/02.OS/02.%E7%BA%BF%E7%A8%8B%E5%92%8C%E8%BF%9B%E7%A8%8B%E5%9F%BA%E7%A1%80.html#解释图1-进程控制块（pcb）" class="sidebar-link">解释图1.进程控制块（PCB）</a></li></ul></li><li><a href="/03.Software/02.OS/02.%E7%BA%BF%E7%A8%8B%E5%92%8C%E8%BF%9B%E7%A8%8B%E5%9F%BA%E7%A1%80.html#_1-进程和线程对比" class="sidebar-link">1.进程和线程对比</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/03.Software/02.OS/02.%E7%BA%BF%E7%A8%8B%E5%92%8C%E8%BF%9B%E7%A8%8B%E5%9F%BA%E7%A1%80.html#_2-进程同步『7侠传』" class="sidebar-link">2.进程同步『7侠传』</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/03.Software/02.OS/02.%E7%BA%BF%E7%A8%8B%E5%92%8C%E8%BF%9B%E7%A8%8B%E5%9F%BA%E7%A1%80.html#_3-线程同步技术『4大天王』" class="sidebar-link">3.线程同步技术『4大天王』</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/03.Software/02.OS/02.%E7%BA%BF%E7%A8%8B%E5%92%8C%E8%BF%9B%E7%A8%8B%E5%9F%BA%E7%A1%80.html#_4-程序员的自我修养，编码链接和库分类" class="sidebar-link">4.程序员的自我修养，编码链接和库分类</a><ul class="sidebar-sub-headers"></ul></li></ul></div></li></ul> </div> <div class="page"> <div class="content"><h1 id="进程和线程基础"><a href="#进程和线程基础" class="header-anchor">#</a> 进程和线程基础</h1> <p>[TOC]</p> <blockquote><p><a href="https://sunweiguo.github.io/2019/11/17/miscellany/20%E5%85%B3%E4%BA%8E%E5%A4%9ACPU%E5%92%8C%E5%A4%9A%E6%A0%B8CPU%E7%9A%84%E5%8C%BA%E5%88%AB/" target="_blank" rel="noopener noreferrer">关于多CPU和多核CPU的区别<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></p></blockquote> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>多进程、进程同步、进程池
多线程、线程同步、线程池
协程
同步、异步、阻塞、非阻塞、轮询
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><div class="tip custom-block"><p class="custom-block-title">多线程-新时代的宠儿</p> <p>『单核CPU』时代和『多核CPU/多CPU』时代</p></div> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>1、单CPU中进程只能是并发，多CPU计算机中进程可以并行
2、『单CPU』『单核』中线程只能并发，『单CPU』『多核』中线程可以并行
3、无论是并发还是并行，使用者来看，看到的是多进程，多线程
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><h2 id="_1-线程和进程认知"><a href="#_1-线程和进程认知" class="header-anchor">#</a> 1.线程和进程认知</h2> <h3 id="_1-1-概念：多任务"><a href="#_1-1-概念：多任务" class="header-anchor">#</a> 1.1.概念：多任务</h3> <ul><li><strong>多任务</strong>可以由<strong>多进程</strong>完成，也可以由一个进程内的<strong>多线程</strong>完成。</li></ul> <h3 id="_1-2-q：多进程和多线程的对比，主要优势对比"><a href="#_1-2-q：多进程和多线程的对比，主要优势对比" class="header-anchor">#</a> 1.2.Q：多进程和多线程的对比，主要优势对比</h3> <ul><li>多进程模型，适用于：CPU密集型</li> <li>多线程模型，<strong>主要优势</strong>为：线程间切换代价较少，因此适用于I/O密集型的工作场景。
<ul><li>『因此，I/O密集型的工作场景经常会由于<strong>I/O阻塞</strong>导致<strong>频繁的切换线程</strong>。</li></ul></li></ul> <h3 id="_1-3-q：为什么需要多线程？"><a href="#_1-3-q：为什么需要多线程？" class="header-anchor">#</a> 1.3.Q：为什么需要多线程？</h3> <ul><li>多线程可以提高程序的执行性能</li></ul> <blockquote><p>继续补充。</p></blockquote> <h3 id="_1-4-q：为什么任何一个线程挂掉都可能直接造成整个进程崩溃？"><a href="#_1-4-q：为什么任何一个线程挂掉都可能直接造成整个进程崩溃？" class="header-anchor">#</a> 1.4.Q：为什么任何一个线程挂掉都可能直接造成整个进程崩溃？</h3> <ul><li>多线程模式致命的缺点就是：因为所有线程『共享进程的内存』</li></ul> <h2 id="_0-图表记忆"><a href="#_0-图表记忆" class="header-anchor">#</a> 0.图表记忆</h2> <h3 id="图1-进程控制块（pcb）"><a href="#图1-进程控制块（pcb）" class="header-anchor">#</a> 图1.进程控制块（PCB）</h3> <img src="/assets/img/进程控制块PCB.03966435.png"> <h3 id="解释图1-进程控制块（pcb）"><a href="#解释图1-进程控制块（pcb）" class="header-anchor">#</a> 解释图1.进程控制块（PCB）</h3> <p>为了管理进程，内核必须对每个进程所做的事情进行『清楚的描述』。
内核为每个进程分配一个<code>PCB(Processing Control Block)</code>进程控制块，维护进程相关的信息，Linux内核的进程控制块是task_struct结构体。</p> <p>其内部成员有很多，我们只需要掌握『<strong>以下部分</strong>』即可:</p> <ul><li>进程id:系统中每个进程有唯一的id，用<code>pid_t</code>类型表示，其实就是一个非负整数</li> <li>进程的状态:有就绪、运行、挂起、停止等状态</li> <li><strong>进程切换</strong>时需要保存和恢复的一些<strong>CPU寄存器</strong></li> <li>描述虚拟地址空间的信息</li> <li>描述控制终端的信息</li> <li>当前工作目录(Current Working Directory)</li> <li>umask掩码</li> <li>文件描述符表，包含很多指向<code>file结构体</code>的指针</li> <li>和信号相关的信息</li> <li>用户id和组id</li> <li>会话(Session和进程组</li> <li>进程可以使用的资源上限(Resource Limit)</li></ul> <h2 id="_1-进程和线程对比"><a href="#_1-进程和线程对比" class="header-anchor">#</a> 1.进程和线程对比</h2> <ul><li><strong>进程</strong>是<strong>资源管理</strong>的最小单位</li> <li><strong>线程</strong>是<strong>程序执行</strong>的最小单位『前提是支持线程』</li> <li>记忆方法：<br> <font style="background:yellow;">大Boss（进程），只管拿着资源统筹兼顾。
小兵（线程），要卖力执行命令</font></li></ul> <h4 id="⭐️进程和线程在两大os的特点"><a href="#⭐️进程和线程在两大os的特点" class="header-anchor">#</a> ⭐️进程和线程在两大OS的特点</h4> <ul><li>Windows对进程和线程的实现如同『教科书』一般标准。</li></ul> <blockquote><ul><li><font style="background:yellow;">Windows内核中有明确的<b>进程</b>和<b>线程</b>的概念</font></li></ul></blockquote> <ul><li>Linux内核中<b>并不存在真正意义上</b>的<b>线程</b>的概念</li></ul> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token operator">-</span> Linux将所有的执行实体（无论是进程还是线程）都称为『『任务（Task）』』

<span class="token operator">-</span> 每个Task概念上都类似于一个单线程的进程，具有内存空间、执行实体、文件资源等。
    
<span class="token operator">-</span> 不过<span class="token punctuation">,</span>Linux下『不同的Task（任务）之间可以选择共享内存空间』，因而在实际意义上，共享了同一个内存空间的多个任务构成了一个进程， 这些任务也就成了这个进程里的线程。
    
<span class="token operator">-</span> Linux下的线程『本质』上用进程实现『牛客题目』
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><h2 id="_2-进程同步『7侠传』"><a href="#_2-进程同步『7侠传』" class="header-anchor">#</a> 2.进程同步『7侠传』</h2> <ul><li>保证2点：进程同步、数据交换</li></ul> <h4 id="⭐️2-1-管道（pipe）"><a href="#⭐️2-1-管道（pipe）" class="header-anchor">#</a> ⭐️2.1.管道（PIPE）</h4> <blockquote><p>(使用最简单)</p></blockquote> <ul><li>有名管道</li> <li>无名管道
<ul><li>语法最方便，代码编写量最少。与管道对应的，另一种通信方式是<strong>fifo</strong>：我们把它称之为“有名管道”，所以有书，称<strong>pipe</strong>管道为：“未名管道”或者“匿名管道”,用于（<strong>非血缘关系</strong>进程间通信）</li></ul></li></ul> <h4 id="⭐️2-2-信号量（semaphore）"><a href="#⭐️2-2-信号量（semaphore）" class="header-anchor">#</a> ⭐️2.2.信号量（Semaphore）</h4> <ul><li>无名线程信号量</li> <li>命名线程信号量🔐</li></ul> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;semaphore.h&gt;</span><span class="token comment">//需要include这个</span></span>

<span class="token keyword">int</span> <span class="token function">sem_init</span><span class="token punctuation">(</span>sem_t <span class="token operator">*</span>sem<span class="token punctuation">,</span> <span class="token keyword">int</span> pshared<span class="token punctuation">,</span> <span class="token keyword">unsigned</span> <span class="token keyword">int</span> value<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> <span class="token function">sem_destroy</span><span class="token punctuation">(</span>sem_t <span class="token operator">*</span>sem<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">int</span> <span class="token function">sem_wait</span><span class="token punctuation">(</span>sem_t <span class="token operator">*</span>sem<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> <span class="token function">sem_post</span><span class="token punctuation">(</span>sem_t <span class="token operator">*</span>sem<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> <span class="token function">sem_getvalue</span><span class="token punctuation">(</span>sem_t <span class="token operator">*</span>sem<span class="token punctuation">,</span> <span class="token keyword">int</span> <span class="token operator">*</span>valp<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><h4 id="⭐️2-3-信号（signal）"><a href="#⭐️2-3-信号（signal）" class="header-anchor">#</a> ⭐️2.3.信号（Signal）</h4> <blockquote><p>(开销最小)</p></blockquote> <ul><li>《Unix环境高级编程》中第10章</li></ul> <div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span><span class="token string">&lt;signal.h&gt;</span>	<span class="token comment">//需要include这个</span></span>
 <span class="token keyword">typedef</span> <span class="token keyword">void</span> <span class="token punctuation">(</span><span class="token operator">*</span><span class="token class-name">sighandler_t</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token keyword">int</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token class-name">sighandler_t</span> <span class="token function">signal</span><span class="token punctuation">(</span><span class="token keyword">int</span> signum<span class="token punctuation">,</span> <span class="token class-name">sighandler_t</span> handler<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><h4 id="⭐️2-4-消息队列（message-queue，mq）"><a href="#⭐️2-4-消息队列（message-queue，mq）" class="header-anchor">#</a> ⭐️2.4.消息队列（Message Queue，MQ）</h4> <div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;sys/msg.h&gt;</span> <span class="token expression"># 消息队列相关函数及数据结构头文件</span></span>


<span class="token keyword">int</span> <span class="token function">msgctl</span><span class="token punctuation">(</span><span class="token keyword">int</span> msqid<span class="token punctuation">,</span> <span class="token keyword">int</span> cmd<span class="token punctuation">,</span> <span class="token keyword">struct</span> <span class="token class-name">msqid_ds</span> <span class="token operator">*</span>buf<span class="token punctuation">)</span><span class="token punctuation">;</span># 控制消息队列函数
<span class="token keyword">int</span> <span class="token function">msgget</span><span class="token punctuation">(</span><span class="token class-name">key_t</span> key<span class="token punctuation">,</span> <span class="token keyword">int</span> msgflg<span class="token punctuation">)</span><span class="token punctuation">;</span> # 创建消息队列，key值唯一标识该消息队列
<span class="token keyword">int</span> <span class="token function">msgrcv</span><span class="token punctuation">(</span><span class="token keyword">int</span> msqid<span class="token punctuation">,</span> <span class="token keyword">void</span> <span class="token operator">*</span>msg_ptr<span class="token punctuation">,</span> <span class="token class-name">size_t</span> msg_sz<span class="token punctuation">,</span> <span class="token keyword">long</span> <span class="token keyword">int</span> msgtype<span class="token punctuation">,</span> <span class="token keyword">int</span> msgflg<span class="token punctuation">)</span><span class="token punctuation">;</span># 接收消息
<span class="token keyword">int</span> <span class="token function">msgsnd</span><span class="token punctuation">(</span><span class="token keyword">int</span> msqid<span class="token punctuation">,</span> <span class="token keyword">const</span> <span class="token keyword">void</span> <span class="token operator">*</span>msg_ptr<span class="token punctuation">,</span> <span class="token class-name">size_t</span> msg_sz<span class="token punctuation">,</span> <span class="token keyword">int</span> msgflg<span class="token punctuation">)</span><span class="token punctuation">;</span># 发送消息
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><h4 id="⭐️2-5-共享内存（shared-memory）"><a href="#⭐️2-5-共享内存（shared-memory）" class="header-anchor">#</a> ⭐️2.5.共享内存（Shared Memory）</h4> <ul><li><p>相对管道，可以在<strong>没有血缘关系</strong>的进程之间，完成数据传递。</p></li> <li><p>共享内存有两种实现方式：1、内存映射 2、共享内存机制</p></li></ul> <blockquote><p>1、内存映射</p></blockquote> <ul><li>内存映射<code>memory map</code>机制使进程之间通过映射同一个普通文件实现共享内存，通过<code>mmap()</code>系统调用实现。</li> <li>普通文件被映射到进程地址空间后，进程可以像访问普通内存一样对文件进行访问，不必再调用read/write等文件操作函数。</li></ul> <blockquote><p>2、UNIX System V共享内存机制</p></blockquote> <ul><li>IPC的共享内存指的是把所有的共享数据放在共享内存区域（IPC shared memory region），任何想要访问该数据的进程都必须在本进程的地址空间新增一块内存区域，用来映射存放共享数据的物理内存页面。</li> <li>和前面的mmap系统调用通过映射一个普通文件实现共享内存不同，<code>UNIX system V</code>共享内存是通过映射特殊文件系统shm中的文件实现进程间的共享内存通信。</li></ul> <blockquote><p>参考资料：<a href="https://www.cnblogs.com/LUO77/p/5816326.html" target="_blank" rel="noopener noreferrer">进程间通信的方式——信号、管道、消息队列、共享内存<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></p></blockquote> <h4 id="⭐️2-6-套接字（socket）"><a href="#⭐️2-6-套接字（socket）" class="header-anchor">#</a> ⭐️2.6.套接字（Socket）</h4> <ul><li>本地套接字，相较于前3种，难度最大，但是稳定性最好</li></ul> <h4 id="⭐️2-7-比如c语言中，新建文件『已经被弃用』"><a href="#⭐️2-7-比如c语言中，新建文件『已经被弃用』" class="header-anchor">#</a> ⭐️2.7.比如C语言中，新建文件『已经被弃用』</h4> <h2 id="_3-线程同步技术『4大天王』"><a href="#_3-线程同步技术『4大天王』" class="header-anchor">#</a> 3.线程同步技术『4大天王』</h2> <img src="/assets/img/线程同步.3130570c.png"> <p>inux下的线程创建、等待、获取线程 id</p> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token keyword">int</span> <span class="token function">pthread_create</span><span class="token punctuation">(</span>pthread_t <span class="token operator">*</span>thread<span class="token punctuation">,</span> <span class="token keyword">const</span> pthread_attr_t <span class="token operator">*</span>attr<span class="token punctuation">,</span> <span class="token keyword">void</span> <span class="token operator">*</span><span class="token punctuation">(</span><span class="token operator">*</span>start_routine<span class="token punctuation">)</span> <span class="token punctuation">(</span><span class="token keyword">void</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword">void</span> <span class="token operator">*</span>arg<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">int</span> <span class="token function">pthread_join</span><span class="token punctuation">(</span>pthread_t thread<span class="token punctuation">,</span> <span class="token keyword">void</span> <span class="token operator">*</span><span class="token operator">*</span>retval<span class="token punctuation">)</span><span class="token punctuation">;</span>
pthread_t <span class="token function">pthread_self</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><ul><li>保证1点：线程同步</li> <li>Tips：线程由于，已经共享内存空间了，所以，没有必要『数据交换』，也就不需要。</li></ul> <h4 id="_1-锁机制（包括下面4种）lock"><a href="#_1-锁机制（包括下面4种）lock" class="header-anchor">#</a> 🔐1.锁机制（包括下面4种）Lock</h4> <ul><li>🔐互斥量/锁（mutex）/互斥体</li> <li>互斥锁是为实现保护共享资源而提出一种锁机制。采用互斥锁保护临界区，防止竞争条件出现。当某个线程无法获取互斥锁时，该线程会被挂起，当其他线程释放互斥锁后，操作系统会唤醒被挂起在这个锁上的线程，让其运行。</li> <li>场景：
<ul><li>1、解决『线程安全』问题，一次只能一个线程访问被保护的资源。</li> <li>2、被保护资源需要『睡眠』，那么可以使用互斥锁</li></ul></li> <li>互斥锁的优化</li></ul> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>- 在Linux下互斥锁的实现是通过『futex』这个基础组件。
- 互斥锁加锁解锁开销很大，需要从用户态切换到内核态，上下文切换以及涉及缓存的更新等等。
通常很多同步操作发生的时候并没有竞争的产生，此时上述开销就没有必要。
考虑到这个因素，futex通过用户空间的共享内存以及原子操作，在共享的资源不存在竞争的时候，不会进行系统调用而是只有当竞争出现的情况下再进行系统调用陷入内核。
进程或者线程在没有竞争的情况下可以立刻获取锁。
具体来说，futex的优化方式如下：
futex将同步过程分为两个部分，一部分由内核完成，一部分由用户态完成；如果同步时没有竞争发生，那么完全在用户态处理；否则，进入内核态进行处理。
『减少系统调用的次数，来提高系统的性能是一种合理的优化方式。』
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;pthread.h&gt;</span><span class="token comment">//需要include的</span></span>
    <span class="token keyword">int</span> <span class="token function">pthread_mutex_init</span><span class="token punctuation">(</span>pthread_mutex_t <span class="token operator">*</span>mutex<span class="token punctuation">,</span> <span class="token keyword">const</span> pthread_mutexattr_t <span class="token operator">*</span>mutexattr<span class="token punctuation">)</span><span class="token punctuation">;</span>  
    <span class="token keyword">int</span> <span class="token function">pthread_mutex_destroy</span><span class="token punctuation">(</span>pthread_mutex_t <span class="token operator">*</span>mutex<span class="token punctuation">)</span><span class="token punctuation">;</span>  

    <span class="token keyword">int</span> <span class="token function">pthread_mutex_lock</span><span class="token punctuation">(</span>pthread_mutex_t <span class="token operator">*</span>mutex<span class="token punctuation">)</span><span class="token punctuation">;</span>  
    <span class="token keyword">int</span> <span class="token function">pthread_mutex_trylock</span><span class="token punctuation">(</span>pthread_mutex_t <span class="token operator">*</span>mutex<span class="token punctuation">)</span><span class="token punctuation">;</span>  
    <span class="token keyword">int</span> <span class="token function">pthread_mutex_unlock</span><span class="token punctuation">(</span>pthread_mutex_t <span class="token operator">*</span>mutex<span class="token punctuation">)</span><span class="token punctuation">;</span> 
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><ul><li>🔐读写锁（reader-writer lock）</li></ul> <div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;pthread.h&gt;</span><span class="token comment">//需要include的</span></span>

<span class="token keyword">int</span> <span class="token function">pthread_rwlock_init</span><span class="token punctuation">(</span><span class="token class-name">pthread_rwlock_t</span> <span class="token operator">*</span>restrict rwlock<span class="token punctuation">,</span> <span class="token keyword">const</span> <span class="token class-name">pthread_rwlockattr_t</span> <span class="token operator">*</span>restrict attr<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> <span class="token function">pthread_rwlock_destroy</span><span class="token punctuation">(</span><span class="token class-name">pthread_rwlock_t</span> <span class="token operator">*</span>rwlock<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">int</span> <span class="token function">pthread_rwlock_rdlock</span><span class="token punctuation">(</span><span class="token class-name">pthread_rwlock_t</span> <span class="token operator">*</span>rwlock<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> <span class="token function">pthread_rwlock_tryrdlock</span><span class="token punctuation">(</span><span class="token class-name">pthread_rwlock_t</span> <span class="token operator">*</span>rwlock<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">int</span> <span class="token function">pthread_rwlock_wrlock</span><span class="token punctuation">(</span><span class="token class-name">pthread_rwlock_t</span> <span class="token operator">*</span>rwlock<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> <span class="token function">pthread_rwlock_trywrlock</span><span class="token punctuation">(</span><span class="token class-name">pthread_rwlock_t</span> <span class="token operator">*</span>rwlock<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">int</span> <span class="token function">pthread_rwlock_unlock</span><span class="token punctuation">(</span><span class="token class-name">pthread_rwlock_t</span> <span class="token operator">*</span>rwlock<span class="token punctuation">)</span><span class="token punctuation">;</span>


——————————————————下面是过时的——————————————————
<span class="token comment">//这两个函数在Linux和Mac的man文档里都没有，新版的pthread.h里面也没有，旧版的能找到</span>
<span class="token keyword">int</span> <span class="token function">pthread_rwlock_timedrdlock_np</span><span class="token punctuation">(</span><span class="token class-name">pthread_rwlock_t</span> <span class="token operator">*</span>rwlock<span class="token punctuation">,</span> <span class="token keyword">const</span> <span class="token keyword">struct</span> <span class="token class-name">timespec</span> <span class="token operator">*</span>deltatime<span class="token punctuation">)</span><span class="token punctuation">;</span>  
<span class="token keyword">int</span> <span class="token function">pthread_rwlock_timedwrlock_np</span><span class="token punctuation">(</span><span class="token class-name">pthread_rwlock_t</span> <span class="token operator">*</span>rwlock<span class="token punctuation">,</span> <span class="token keyword">const</span> <span class="token keyword">struct</span> <span class="token class-name">timespec</span> <span class="token operator">*</span>deltatime<span class="token punctuation">)</span><span class="token punctuation">;</span> 
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br></div></div><ul><li>🔐自旋锁（spin lock）</li> <li>自旋锁也是为实现保护共享资源而提出一种锁机制。</li> <li>自旋锁不会引起调用线程阻塞，如果自旋锁已经被别的线程持有，调用线程就一直循环检测是否该自旋锁已经被释放。</li></ul> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token keyword">int</span> <span class="token function">pthread_spin_init</span> <span class="token punctuation">(</span>__pthread_spinlock_t <span class="token operator">*</span>__lock<span class="token punctuation">,</span> <span class="token keyword">int</span> __pshared<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> <span class="token function">pthread_spin_destroy</span> <span class="token punctuation">(</span>__pthread_spinlock_t <span class="token operator">*</span>__lock<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> <span class="token function">pthread_spin_lock</span> <span class="token punctuation">(</span>__pthread_spinlock_t <span class="token operator">*</span>__lock<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> <span class="token function">pthread_spin_trylock</span> <span class="token punctuation">(</span>__pthread_spinlock_t <span class="token operator">*</span>__lock<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> <span class="token function">pthread_spin_unlock</span> <span class="token punctuation">(</span>__pthread_spinlock_t <span class="token operator">*</span>__lock<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><ul><li>⭐️<strong>条件变量</strong>（condition）</li></ul> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;pthread.h&gt;</span><span class="token comment">//需要include的</span></span>
<span class="token keyword">int</span> <span class="token function">pthread_cond_init</span><span class="token punctuation">(</span>pthread_cond_t <span class="token operator">*</span>restrict cond<span class="token punctuation">,</span> <span class="token keyword">const</span> pthread_condattr_t <span class="token operator">*</span>restrict attr<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> <span class="token function">pthread_cond_destroy</span><span class="token punctuation">(</span>pthread_cond_t <span class="token operator">*</span>cond<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> <span class="token function">pthread_cond_wait</span><span class="token punctuation">(</span>pthread_cond_t <span class="token operator">*</span>restrict cond<span class="token punctuation">,</span> pthread_mutex_t <span class="token operator">*</span>restrict mutex<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> <span class="token function">pthread_cond_timedwait</span><span class="token punctuation">(</span>pthread_cond_t <span class="token operator">*</span>restrict cond<span class="token punctuation">,</span> pthread_mutex_t <span class="token operator">*</span>restrict mutex<span class="token punctuation">,</span> <span class="token keyword">const</span> <span class="token keyword">struct</span> <span class="token class-name">timespec</span> <span class="token operator">*</span>restrict abstime<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">int</span> <span class="token function">pthread_cond_signal</span><span class="token punctuation">(</span>pthread_cond_t <span class="token operator">*</span>cond<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> <span class="token function">pthread_cond_broadcast</span><span class="token punctuation">(</span>pthread_cond_t <span class="token operator">*</span>cond<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><h4 id="⭐️2-信号量机制（semaphore）"><a href="#⭐️2-信号量机制（semaphore）" class="header-anchor">#</a> ⭐️2.信号量机制（Semaphore）</h4> <ul><li>无名线程信号量</li> <li>命名线程信号量</li></ul> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;semaphore.h&gt;</span><span class="token comment">//需要include这个</span></span>

<span class="token keyword">int</span> <span class="token function">sem_init</span><span class="token punctuation">(</span>sem_t <span class="token operator">*</span>sem<span class="token punctuation">,</span> <span class="token keyword">int</span> pshared<span class="token punctuation">,</span> <span class="token keyword">unsigned</span> <span class="token keyword">int</span> value<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> <span class="token function">sem_destroy</span><span class="token punctuation">(</span>sem_t <span class="token operator">*</span>sem<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> <span class="token function">sem_wait</span><span class="token punctuation">(</span>sem_t <span class="token operator">*</span>sem<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//（相当于加锁，表示--）</span>
<span class="token keyword">int</span> <span class="token function">sem_post</span><span class="token punctuation">(</span>sem_t <span class="token operator">*</span>sem<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//（相当于解锁，表示++）</span>
<span class="token keyword">int</span> <span class="token function">sem_getvalue</span><span class="token punctuation">(</span>sem_t <span class="token operator">*</span>sem<span class="token punctuation">,</span> <span class="token keyword">int</span> <span class="token operator">*</span>valp<span class="token punctuation">)</span><span class="token punctuation">;</span>

sem_trywait函数
sem_timedwait函数
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br></div></div><h4 id="⭐️3-信号机制（signal）"><a href="#⭐️3-信号机制（signal）" class="header-anchor">#</a> ⭐️3.信号机制（Signal）</h4> <ul><li>《Unix环境高级编程》中第10章</li></ul> <div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span><span class="token string">&lt;signal.h&gt;</span>	<span class="token comment">//需要include这个</span></span>

<span class="token keyword">typedef</span> <span class="token keyword">void</span> <span class="token punctuation">(</span><span class="token operator">*</span><span class="token class-name">sighandler_t</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token keyword">int</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token class-name">sighandler_t</span> <span class="token function">signal</span><span class="token punctuation">(</span><span class="token keyword">int</span> signum<span class="token punctuation">,</span> <span class="token class-name">sighandler_t</span> handler<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><h4 id="⭐️4-屏障（barrier）"><a href="#⭐️4-屏障（barrier）" class="header-anchor">#</a> ⭐️4.屏障（barrier）</h4> <blockquote><p>参考：<a href="https://blog.nowcoder.net/n/e26967a0bfa44ffb9836c0713412d4a7" target="_blank" rel="noopener noreferrer">Linux C/C++ 后台开发实习生技能要求<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></p></blockquote> <h2 id="_4-程序员的自我修养，编码链接和库分类"><a href="#_4-程序员的自我修养，编码链接和库分类" class="header-anchor">#</a> 4.程序员的自我修养，编码链接和库分类</h2> <ul><li><p>下面的说法来自《程序员的自我修养，编码链接和库》，感觉分类不正确</p></li> <li><p>同步的各种锁：</p></li></ul> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>（1）信号量
（严格程度：低）二元信号量（Binary Semaphore）是最简单的一种锁，它只有两种状态:占用与非占用。
它适合只能被唯一个线程独占访问的资源。当二元信号量处于非占用状态时，第一个试图获取该二元信号量的线程会获得该锁，并将二元信号量置为占用状态，此后其他的所有试图获取该二元信号量的线程将会等待，直到该锁被释放。
- 对于允许多个线程并发访问的资源，&lt;b&gt;多元信号量简称信号量(Semaphore)&lt;/b&gt;,它是一个很好的选择。一个初始值为N的信号量允许N个线程并发访问。线程访问资源的时候首先获取信号量，进行如下操作:
- 将信号量的值减1。
- 如果信号量的值小于0，则进入等待状态，否则继续执行。
- 访问完资源之后，线程释放信号量，进行如下操作:
- 将信号量的值加1。
- 如果信号量的值小于1,唤醒-一个等待中的线程。


（严格程度：中）互斥量（Mutex）和二元信号量很类似，资源仅同时允许一个线程访问，但和信号量不同的是:
1）信号量在整个系统可以被任意线程获取并释放，也就是说，同一个信号量可以被系统中的一个线程获取之后的&lt;font style=&quot;background: yellow&quot;&gt;另一个线程&lt;/font&gt;释放。
2）互斥量则要求哪个线程获取了互斥量，哪个线程就要负责释放这个锁，其他线程越俎代庖去释放互斥量是无效的。



（严格程度：高）临界区（Critical Section）是比互斥量更加严格的同步手段。
在术语中，把临界区的锁的获取称为进入临界区,而把锁的程放称为离开临界区。
临界区和互斥量与信号量的区别在于:
1）&lt;b&gt;互斥量和信号量&lt;/b&gt;在系统的&lt;font style=&quot;background: yellow&quot;&gt;&lt;b&gt;任何进程&lt;/b&gt;&lt;/font&gt;里都是可见的，也就是说，一个进程创建了一个互斥量或信号量,另一个进程试图去获取该锁是合法的。
2）&lt;b&gt;临界区&lt;/b&gt;的作用范围&lt;font style=&quot;background: yellow&quot;&gt;&lt;b&gt;仅限于本进程&lt;/b&gt;&lt;/font&gt;，其他的进程无法获取该锁。除此之外，临界区具有和互斥量相同的性质。




（2）读写锁（Read-Write Lock）
- 由来：对于一段数据，多个线程同时读取总是没有问题的，但假设操作都不是原子型，只要有任何一个线程试图对这个数据进行修改，就必须使用同步手段来避免出错。如果我们使用上述信号量、互斥量或临界区中的任何一种来进行同步，尽管可以保证程序正确，但&lt;b&gt;对于读取频繁，而仅仅偶尔写入的情况&lt;/b&gt;，会显得非常低效。
- 读写锁(Read-Write Lock)致力于一种更加特定的场合的同步:&lt;b&gt;读取频繁，偶尔写入的情况&lt;/b&gt;
- 读写锁可以避免这个问题。对于同一个锁，读写锁有两种获取方式，&lt;b&gt;共享的(Shared)&lt;/b&gt;或&lt;b&gt;独占(Exclusive)&lt;/b&gt;。
- 当锁处于自由的状态时，试图以任何一种方式获取锁都能成功，并将锁置于对应的状态。
- 如果锁处于共享状态，其他线程以共享的方式获取锁仍然会成功，此时这个锁分配给了多个线程。然而，如果其他线程试图以独身的方式获取已经处于共享状态的锁，那么它将必须等待锁被所有的线程释放。
- 相应地，处于独占状态的锁将阻止任何其他线程获取该锁，不论它们试图以哪种方式获取。


（3）条件变量（Condition Variable） 作为一种同步手段，作用类似于一个栅栏。
- 对于条件变量，线程可以有两种操作，首先线程可以等待条件变量，一个条件变量可以被多个线程等待。
- 其次，线程可以唤醒条件变量,此时某个或所有等待此条件变量的线程都会被唤醒并继续支持。也就是说，使用条件变量可以让许多线程-起等待某个事件的发生，当事件发生时(条件变量被唤醒)，所有的线程可以一起恢复执行。
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br></div></div></div> <div class="page-edit"><!----> <!----></div> <!----> </div> <!----></div></div>
    <script src="/assets/js/app.c70e21ad.js" defer></script><script src="/assets/js/5.6f47322c.js" defer></script>
  </body>
</html>
